/*
 *  src/process_control.c
 *
 *  Harry Wei <harryxiyou@gmail.com> (C) 2011
 */
#include <stdlib.h>
#include <glib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

#define SHM_SIZE 30

extern etext;
extern edata;
extern end;

void shm1(void)
{
	pid_t pid;
	int shmid;
	char c;
	char *shm = NULL;
	char *s = NULL;

	if ((shmid = shmget(IPC_PRIVATE, SHM_SIZE, IPC_CREAT | 0666)) < 0) {
		perror("shmget fail");
		exit(1);
	}
	if ((shm = (char *)shmat(shmid, 0, 0)) == (char *) -1) {
		perror("shmat : parent");
		exit(2);
	}
	g_print("Address in parent\n\n");
	g_print("shared mem: %X etext; %X edata: %X end: %X\n\n", 
			(unsigned int) shm, (unsigned int) etext, (unsigned int) edata, (unsigned int) end);
	s = shm;
	for (c = 'A'; c <= 'Z'; c++) {
		*s = c;
		s += 1;
	}
	s = NULL;
	g_print("In parent before fork, memory is: %s\n", shm);
	pid = fork();
	switch (pid) {
		case -1:
			perror("fork\n");
			exit(3);
		case 0:
			g_print("In child after fork, memory is: %s\n", shm);
			for (; *shm; shm++) {
				*shm += 32;
			}
//			shmdt(shm);
			exit(0);
		default:
			sleep(5);
			g_print("\nIn parent after fork, memory is: %s\n", shm);
			g_print("Parent removing shared memory\n");
			if (-1 == shmdt(shm)) {
				g_message("%s -- shmdt error!\n", __func__);
				return ;
			}
			if (-1 == shmctl(shmid, IPC_RMID, (struct shmid_ds *) 0)) {
				g_message("%s -- shmctl error!\n", __func__);
				return ;
			}
			exit(0);
	}
//	return 0;
}
